#define SUCCES 0
#define ITEM_NOT_FOUND -1
#define INVENTORY_FULL -2


class UI_ELEM_Inventory
{
	int xPos,yPos;

public:

	int width;
	int height;
	
	/******************************************/
	int coins; // lolz moneyz
	/******************************************/

	int itemsInPool;
	inventory_Item* itemPool[100000];
	inventory_Item empty;

	inventory_Item itemSlots[30];

	int unlockedRows;

	int selectedSlot;

	Button unlockSlot;
	Vector fuck,fock;
	int unlockConfirm;

	Button useItem,dropItem,equipItem,destroyItem;

	int confirmDestroyItem;
	

	UI_ELEM_Inventory()
	{
		confirmDestroyItem = NULL;
		unlockConfirm = NULL;
		selectedSlot;
		itemsInPool = 0;
		width = 670;
		height = 500;
		xPos = 0;
		yPos = 0;
		coins = 13370;
		unlockedRows = 0;
		
		unlockSlot.Init(fuck,fock);
		unlockSlot.SetActiveColor(0.0f,0.5f,0.95f);
		unlockSlot.SetActiveSpecColor(0.0f,0.2f,0.9f);
		unlockSlot.SetColor(0.0f,0.5f,0.95f);
		unlockSlot.SetSpecColor(0.0f,0.2f,0.9f);
		unlockSlot.SetStyle(SHADED);
		unlockSlot.SetSpecialStyle(SHADED);
		unlockSlot.SetActiveStyle(SHADED);
		unlockSlot.SetActiveSpecialStyle(SHADED);

		useItem.Init(fuck,fock);
		useItem.SetActiveColor(0.0f,0.5f,0.95f);
		useItem.SetActiveSpecColor(0.0f,0.8f,0.9f);
		useItem.SetColor(0.0f,0.9f,0.95f);
		useItem.SetSpecColor(0.0f,0.2f,0.9f);
		useItem.SetStyle(NONE);
		useItem.SetSpecialStyle(SHADED);
		useItem.SetActiveStyle(NONE);
		useItem.SetActiveSpecialStyle(SHADED);
		useItem.SetButtonExecMode(RUNONCE);

		dropItem = useItem;
		equipItem = useItem;
		destroyItem = useItem;
	}

	~UI_ELEM_Inventory()
	{
		//cout << "WHY THE FUCK IS IT CALLING THIS FUCKING DESTRUCTOR??" << endl;
	}


	void setPos(int x,int y)
	{
		xPos =x;
		yPos =y;
	}

	int delItem(string fileName,int quantity)
	{
		for(int counter = 0;counter < getnOfSlots();counter++)
		{
			if(itemSlots[counter].fileName == fileName)
			{
				itemSlots[counter] = empty;
				quantity--;

				if(quantity==0)
					return SUCCES;
			}
		}
		if(quantity == 0)
			return SUCCES;
		else
			return ITEM_NOT_FOUND; // item not found
	}

	int addItem(string fileName,int quantity)
	{
		cout << "Adding item \"" << fileName << "\" to inventory." << endl;
		int initialQuant = quantity;
		bool loaded = false;
		int poolId = 0;

		for(int counter = 0;counter < itemsInPool;counter++)
		{
			if(itemPool[counter]->fileName == fileName)
			{
				loaded = true;
				poolId = counter;
				counter = 99999999;
			}
		}
		if(loaded == false)
		{
	
			itemPool[itemsInPool] = new inventory_Item;
			itemPool[itemsInPool]->load(fileName);
			poolId = itemsInPool;
			itemsInPool++;
		}
		
		for(int counter = 0;counter < getnOfSlots();counter++)
		{
			if(itemPool[poolId]->stackable && itemSlots[counter].fileName == itemPool[poolId]->fileName && itemSlots[counter].quantity < itemPool[poolId]->stackSize)
			{
				bool dipshit = true;
				while(dipshit)
				{
					if(itemSlots[counter].quantity < itemSlots[counter].stackSize)
					{
						itemSlots[counter].quantity++;
						quantity--;
					}
					else
						dipshit = false;

					if(quantity == 0)
					{
						logPrint("You received item '"+itemPool[poolId]->itemName+"'x"+intToString(initialQuant)+".");
						return SUCCES;
					}
				}
			}
			else if(itemSlots[counter].itemName == "NO_ITEM")
			{
				itemSlots[counter] = *itemPool[poolId];

				if(itemPool[poolId]->stackable)
				{
					if(quantity <= itemPool[poolId]->stackSize)
					{
						itemSlots[counter].quantity = quantity;
						quantity = 0;
					}
					else
					{
						itemSlots[counter].quantity = itemPool[poolId]->stackSize;
						quantity -= itemPool[poolId]->stackSize;
					}
				}
				else
					quantity--;

				if(quantity == 0)
				{
					if(initialQuant > 1)
						logPrint("You received item '"+itemPool[poolId]->itemName+"'x"+intToString(initialQuant)+".");
					else
						logPrint("You received item '"+itemPool[poolId]->itemName+"'.");

					return SUCCES;
				}
			}
		}

		if(quantity > 0)
		{
			logPrint("Inventory is full.");
			return INVENTORY_FULL;
		}

		return SUCCES;
	}


	void handler()
	{
		// shadows :)
		defaultFont.setScale(2.0);
		defaultFont.setColor(0,0,0.3,1);
		defaultFont.printString(xPos+38,yPos-53,"Inventory");

		defaultFont.setScale(1.0);
		defaultFont.printString(xPos+313,yPos-53,"Space: "+intToString(getnOfSlots()-getEmptySlots())+"/"+intToString(getnOfSlots()));
		defaultFont.printString(xPos+503,yPos-53,"Coins: "+intToString(coins)); 

		// text
		defaultFont.setScale(2.0);
		defaultFont.setColor(0.5,0.7,1,1);
		defaultFont.printString(xPos+35,yPos-50,"Inventory");

		defaultFont.setScale(1.0);
		defaultFont.printString(xPos+310,yPos-50,"Space: "+intToString(getnOfSlots()-getEmptySlots())+"/"+intToString(getnOfSlots()));
		defaultFont.printString(xPos+500,yPos-50,"Coins: "+intToString(coins));

		drawMiniMenuBase();

		pushMatrix();
		translatef(0,-195,0);
		drawMiniMenuBase();
		popMatrix();

		updateSlots();
		handleItemButtons();
		itemMenu();
		doRandomShit();
		
	}

	void handleItemButtons()
	{
		fuck.x = xPos+15;
		fuck.y = -(yPos-140);
		fock.x = xPos+235;
		fock.y = -(yPos-110);
		
		equipItem.SetPosition(fuck,fock);

		fuck.x = xPos+15;
		fuck.y = -(yPos-170);
		fock.x = xPos+235;
		fock.y = -(yPos-140);

		useItem.SetPosition(fuck,fock);

		fuck.x = xPos+15;
		fuck.y = -(yPos-200);
		fock.x = xPos+235;
		fock.y = -(yPos-170);

		dropItem.SetPosition(fuck,fock);

		fuck.x = xPos+15;
		fuck.y = -(yPos-230);
		fock.x = xPos+235;
		fock.y = -(yPos-200);

		destroyItem.SetPosition(fuck,fock);

		if(itemSlots[selectedSlot].equipable)
		{
			equipItem.CheckState(mouseX,mouseY,WIN_HEIGHT,s_leftbutton);
			equipItem.Render();
		}
		if(itemSlots[selectedSlot].useable)
		{
			useItem.CheckState(mouseX,mouseY,WIN_HEIGHT,s_leftbutton);
			useItem.Render(); 
		}
		if(itemSlots[selectedSlot].droppable)
		{
			dropItem.CheckState(mouseX,mouseY,WIN_HEIGHT,s_leftbutton);
			dropItem.Render();
		}
		if(itemSlots[selectedSlot].itemName != "NO_ITEM")
		{
			destroyItem.CheckState(mouseX,mouseY,WIN_HEIGHT,s_leftbutton);
			destroyItem.Render();
		}

		// Destroy button

		if(destroyItem.GetState())
		{
			MsgBox("Are you sure you want to permanently\nremove this item from your inventory?","Destroy item",B_YESNO,&confirmDestroyItem);
		}

		if(confirmDestroyItem == ID_YES)
		{
			itemSlots[selectedSlot] = empty;
			confirmDestroyItem = NULL;
		}
		if(confirmDestroyItem == ID_NO)
			confirmDestroyItem = NULL;

		// Drop button
		if(dropItem.GetState())
		{
			// Delete the item and spawn the object on the map.

			Vector pos = getPlayerCoord();

			addObject(itemSlots[selectedSlot].objectName,pos.x+PLAYER_WIDTH/2,pos.y);
			itemSlots[selectedSlot] = empty;

			for(int counter = 0;counter < getnOfSlots();counter++)
			{
				if(itemSlots[counter].itemName != "NO_ITEM")
				{
					selectedSlot = counter;
					dropItem.SetState(false);
					return;
				}
			}
			dropItem.SetState(false);
			return;
		}
		// Use button

		if(useItem.GetState())
		{
			itemSlots[selectedSlot].runscript();
		}

		// Equip button

		if(equipItem.GetState())
		{
			//cout << "Equipping item in inv slot " << selectedSlot << endl;
			EquipItem(itemSlots[selectedSlot]);
			//cout << "UFYGEAUFOAIU" << endl;
			equipItem.SetState(false);
			return;
		}

	}

	void doRandomShit()
	{
		fuck.x = xPos+350;
		fuck.y = -(yPos-420);
		fock.x = xPos+560;
		fock.y = -(yPos-480);

		unlockSlot.SetPosition(fuck,fock);
		unlockSlot.CheckState(mouseX,mouseY,WIN_HEIGHT,s_leftbutton);
		unlockSlot.Render();


		glLineWidth(2.0);
		setColor3f(0.5,0.6,1);
		drawLineLoop(fuck.x,-fuck.y,fock.x,-fock.y);

		defaultFont.setScale(1.20);
		defaultFont.setColor(0,0,0.3,1);

		defaultFont.printString(xPos+358,yPos-468,"Expand inventory");

		defaultFont.setScale(1.20);
		defaultFont.setColor(0.5,0.7,1,1);
		defaultFont.printString(xPos+355,yPos-465,"Expand inventory");

		if(unlockedRows == 3)
		{
			setColor4f(0,0,0,0.8);
			drawQuad(fuck.x-1,-fuck.y+1,fock.x+1,-fock.y-1);
		}

		if(unlockSlot.GetState() && unlockedRows < 3)
		{
			MsgBox("Are you sure you wish to buy extra item slots? (<PH: expandCost> Coins)","Expand inventory",B_YESNO,&unlockConfirm);
		}

		if(unlockConfirm == ID_YES)
		{
			if(unlockedRows < 3)
			{
				if(unlockedRows == 0)
					coins -= 1000;
				if(unlockedRows == 1)
					coins -= 5000;
				if(unlockedRows == 2)
					coins -= 15000;
				
				unlockConfirm = NULL;
				unlockedRows++;
			}
			else
			{
				unlockConfirm = NULL;
				MsgBox("What is this? I don't even...","Error");
			}
		}
		if(unlockConfirm == ID_NO)
			unlockConfirm = NULL;
		
	}

	

	void drawMiniMenuBase()
	{
		// Draw dark blue background
		glColor4f(0,0,0.8f,0.95f);
		drawQuad(xPos+5,yPos-55,xPos+245,yPos-250);

		// Upper light blue bar
		glColor3f(0.0f,0.5f,0.95f);
		glBegin(GL_QUADS);
		glVertex2i(xPos+5,yPos-55);
		glVertex2i(xPos+245,yPos-55);	
		glColor3f(0.0f,0.2f,0.9f);
		glVertex2i(xPos+245,yPos-100);
		glVertex2i(xPos+5,yPos-100);
		glEnd();

		// upper black shade
		glColor4f(0.0f,0.0f,0.0f,0.4f);
		glBegin(GL_QUADS);
		glVertex2i(xPos+5,yPos-100);
		glVertex2i(xPos+245,yPos-100);	
		glColor4f(0.0f,0.0f,0.0f,0.0f);
		glVertex2i(xPos+245,yPos-180);
		glVertex2i(xPos+5,yPos-180);
		glEnd();

		
		// Lower light blue bar
		glColor3f(0.0f,0.5f,0.95f);
		glBegin(GL_QUADS);
		glVertex2i(xPos+5,yPos-250);
		glVertex2i(xPos+245,yPos-250);	
		glColor3f(0.0f,0.2f,0.9f);
		glVertex2i(xPos+245,yPos-295);
		glVertex2i(xPos+5,yPos-295);
		glEnd();

		// lower black shade
		glColor4f(0.0f,0.0f,0.0f,0.4f);
		glBegin(GL_QUADS);
		glVertex2i(xPos+5,yPos-250);
		glVertex2i(xPos+245,yPos-250);	
		glColor4f(0.0f,0.0f,0.0f,0.0f);
		glVertex2i(xPos+245,yPos-200);
		glVertex2i(xPos+5,yPos-200);
		glEnd();
	}

	int getnOfSlots()
	{
		return 6*2+(unlockedRows*6);
	}

	int getEmptySlots()
	{
		int emptySlots = 0;
		for(int counter = 0;counter < getnOfSlots();counter++)
		{
			if(itemSlots[counter].itemName == "NO_ITEM")
				emptySlots++;
		}
		return emptySlots;
	}

	void updateSlots()
	{
		int x = xPos+270;
		int y = yPos-50;

		for(int counter = 0;counter < 6*5;counter++)
		{
			if((counter%6)==0)
			{
				x = xPos+250;
				y -= 70;
			}

			itemSlots[counter].drawContent(x,y);
			x += 70;
		}

		for(int counter = 0;counter < 6*5;counter++)
		{
			if(itemSlots[counter].butt.MouseOver() && itemSlots[counter].itemName != "NO_ITEM")
				itemSlots[counter].viewInfo();
			if(itemSlots[counter].leftState)
				selectedSlot = counter;
		}

		for(int counter = 0;counter < 6*5;counter++)
		{
			if(selectedSlot != counter)
				itemSlots[counter].selected = false;
			else 
				itemSlots[counter].selected = true;
		}

		defaultFont.setColor(1,1,1,0.25);
		defaultFont.setScale(1.7);
		

		if(unlockedRows == 0)
		{
			setColor4f(0,0,0,0.75f);
			drawQuad(xPos+245,yPos-405,xPos+665,yPos-195);
			defaultFont.printString(xPos+365,yPos-245,"    Locked");
			defaultFont.printString(xPos+365,yPos-315,"    Locked");
			defaultFont.printString(xPos+365,yPos-385,"    Locked");
		}
		if(unlockedRows == 1)
		{
			setColor4f(0,0,0,0.75f);
			drawQuad(xPos+245,yPos-405,xPos+665,yPos-265);
			defaultFont.printString(xPos+365,yPos-315,"    Locked");
			defaultFont.printString(xPos+365,yPos-385,"    Locked");
		}
		if(unlockedRows == 2)
		{
			setColor4f(0,0,0,0.75f);
			drawQuad(xPos+245,yPos-405,xPos+665,yPos-335);
			defaultFont.printString(xPos+365,yPos-385,"    Locked");
		}
		
	}

	void itemMenu()
	{
		// Draw text shadows 
		defaultFont.setScale(1.3f);
		defaultFont.setColor(0,0,0.3,1.0f);
		
		defaultFont.printString(xPos+23,yPos-143,"Equip");
		defaultFont.printString(xPos+23,yPos-173,"Use");
		defaultFont.printString(xPos+23,yPos-203,"Drop");
		defaultFont.printString(xPos+23,yPos-233,"Destroy");

		defaultFont.setScale(0.95f);

		defaultFont.printString(xPos+13,yPos-333,itemSlots[selectedSlot].itemName);

		printItemType_Shadows();

		if(itemSlots[selectedSlot].stackable)
		{
			defaultFont.printString(xPos+13,yPos-373,"Maximum stack size: "+intToString(itemSlots[selectedSlot].stackSize));
		}
		else
			defaultFont.printString(xPos+13,yPos-373,"This item does not stack.");
		

		// Draw actual text
		defaultFont.setScale(1.3f);
		defaultFont.setColor(0.5,0.7,1,1);

		defaultFont.printString(xPos+20,yPos-140,"Equip");
		defaultFont.printString(xPos+20,yPos-170,"Use");
		defaultFont.printString(xPos+20,yPos-200,"Drop");
		defaultFont.printString(xPos+20,yPos-230,"Destroy");

		defaultFont.setScale(0.95f);

		defaultFont.printString(xPos+10,yPos-330,itemSlots[selectedSlot].itemName);

		printItemType_Base();

		if(itemSlots[selectedSlot].stackable)
		{
			defaultFont.printString(xPos+10,yPos-370,"Maximum stack size: "+intToString(itemSlots[selectedSlot].stackSize));
		}
		else
			defaultFont.printString(xPos+10,yPos-370,"This item does not stack.");

		glColor4f(0,0,0,0.7f);

		if(itemSlots[selectedSlot].equipable==false)
			drawQuad(xPos+15,yPos-140,xPos+235,yPos-110);
		if(itemSlots[selectedSlot].useable==false)
			drawQuad(xPos+15,yPos-170,xPos+235,yPos-140);
		if(itemSlots[selectedSlot].droppable==false)
			drawQuad(xPos+15,yPos-200,xPos+235,yPos-170);
		//if(itemSlots[selectedSlot].destructable==false)
			//drawQuad(xPos+15,yPos-233,xPos+235,yPos-200);
	}

	void printItemType_Shadows()
	{
		if(itemSlots[selectedSlot].itemType == "QUEST")
		{
			defaultFont.printString(xPos+13,yPos-353,"Quest item");
		}
		if(itemSlots[selectedSlot].itemType == "CONSUMABLE")
		{
			defaultFont.printString(xPos+13,yPos-353,"Consumable");
		}
		if(itemSlots[selectedSlot].itemType == "WEAPON_2H")
		{
			defaultFont.printString(xPos+13,yPos-353,"2 Handed weapon");
		}
		if(itemSlots[selectedSlot].itemType == "WEAPON_MAINHAND")
		{
			defaultFont.printString(xPos+13,yPos-353,"Main hand weapon");
		}
		if(itemSlots[selectedSlot].itemType == "WEAPON_OFFHAND")
		{
			defaultFont.printString(xPos+13,yPos-353,"Offhand weapon");
		}
		if(itemSlots[selectedSlot].itemType == "SHIELD")
		{
			defaultFont.printString(xPos+13,yPos-353,"Shield");
		}
		if(itemSlots[selectedSlot].itemType == "ARMOR_HEAD")
		{
			defaultFont.printString(xPos+13,yPos-353,"Head");
		}
		if(itemSlots[selectedSlot].itemType == "ARMOR_CHEST")
		{
			defaultFont.printString(xPos+13,yPos-353,"Chest");
		}
		if(itemSlots[selectedSlot].itemType == "ARMOR_LEGS")
		{
			defaultFont.printString(xPos+13,yPos-353,"Legs");
		}
		if(itemSlots[selectedSlot].itemType == "ARMOR_FEET")
		{
			defaultFont.printString(xPos+13,yPos-353,"Boots");
		}
		if(itemSlots[selectedSlot].itemType == "ARMOR_NECK")
		{
			defaultFont.printString(xPos+13,yPos-353,"Necklace");
		}
		if(itemSlots[selectedSlot].itemType == "ARMOR_RING")
		{
			defaultFont.printString(xPos+13,yPos-353,"Ring");
		}
	}

	void printItemType_Base()
	{
		if(itemSlots[selectedSlot].itemType == "QUEST")
		{
			defaultFont.printString(xPos+10,yPos-350,"Quest item");
		}
		if(itemSlots[selectedSlot].itemType == "CONSUMABLE")
		{
			defaultFont.printString(xPos+10,yPos-350,"Consumable");
		}
		if(itemSlots[selectedSlot].itemType == "WEAPON_2H")
		{
			defaultFont.printString(xPos+10,yPos-350,"2 Handed weapon");
		}
		if(itemSlots[selectedSlot].itemType == "WEAPON_MAINHAND")
		{
			defaultFont.printString(xPos+10,yPos-350,"Main hand weapon");
		}
		if(itemSlots[selectedSlot].itemType == "WEAPON_OFFHAND")
		{
			defaultFont.printString(xPos+10,yPos-350,"Offhand weapon");
		}
		if(itemSlots[selectedSlot].itemType == "SHIELD")
		{
			defaultFont.printString(xPos+10,yPos-350,"Shield");
		}
		if(itemSlots[selectedSlot].itemType == "ARMOR_HEAD")
		{
			defaultFont.printString(xPos+10,yPos-350,"Head");
		}
		if(itemSlots[selectedSlot].itemType == "ARMOR_CHEST")
		{
			defaultFont.printString(xPos+10,yPos-350,"Chest");
		}
		if(itemSlots[selectedSlot].itemType == "ARMOR_LEGS")
		{
			defaultFont.printString(xPos+10,yPos-350,"Legs");
		}
		if(itemSlots[selectedSlot].itemType == "ARMOR_FEET")
		{
			defaultFont.printString(xPos+10,yPos-350,"Boots");
		}
		if(itemSlots[selectedSlot].itemType == "ARMOR_NECK")
		{
			defaultFont.printString(xPos+10,yPos-350,"Necklace");
		}
		if(itemSlots[selectedSlot].itemType == "ARMOR_RING")
		{
			defaultFont.printString(xPos+10,yPos-350,"Ring");
		}
	}

};